/**
 * Menu 组件
 */
import React, {
  useState, createContext, FC, CSSProperties, Children,
  FunctionComponentElement, cloneElement,
} from 'react';
import classNames from 'classnames';
import { IMenuItemProps } from './menuItem';

type MenuMode = 'horizontal' | 'vertical';
type SelectCallBack = (selectedIndex: string) => void;

export interface IMenuProps {
  /**默认选中项 */
  defaultIndex?: string;

  /**样式类名 */
  className?: string;

  /**展示模式 horizontal 横向 vertical 纵向 */
  mode?: MenuMode;

  style?: CSSProperties;

  /**选中的项 */
  onSelect?: SelectCallBack;

  /**默认展开项，作用于 submenu */
  defaultOpenKeys?: string[];
}

interface IMenuContext {
  index: string;
  onSelect?: SelectCallBack;
  mode?: MenuMode;
  defaultOpenKeys?: string[];
}

// 传递给子组件的 context
export const MenuContext = createContext<IMenuContext>({ index: '0' });

/**
 * 页面通用菜单组件
 * 
 * ### 引入方式 
 * 
 * ```js 
 * import { Menu } from 'rqx-ui';
 * 
 * const { MenuItem } = Menu;
 * const { SubMenu } = Menu;
 * 
 * ```
 */
export const Menu: FC<IMenuProps> = (props) => {
  const {
    className,
    mode,
    style,
    children,
    defaultIndex,
    onSelect,
    defaultOpenKeys,
    ...rest
  } = props;

  const [currentActive, setActive] = useState(defaultIndex);

  const classes = classNames('menu', className, {
    'menu-vertical': mode === 'vertical',
    'menu-horizontal': mode !== 'vertical',
  });

  // 点击事件
  const handleClick = (index: string) => {
    setActive(index); // 激活点击的item
    if(onSelect) {
      onSelect(index);
    }
  }

  // 向下层传递的数据
  const contextValue: IMenuContext = {
    index: currentActive ? currentActive : '0',
    onSelect: handleClick,
    mode,
    defaultOpenKeys,
  };

  // 向子节点传递 属性
  const renderChildren = () => {
    return Children.map(children, (child, index) => {
      const childElement = child as FunctionComponentElement<IMenuItemProps>;
      const { displayName } = childElement.type;
      if(displayName !== 'MenuItem' && displayName !== 'SubMenu'){
        console.error('Warning: Menu has a child which is not a MenuItem component');
        return;
      }

      return cloneElement(childElement, {
        index: index.toString(),
      });
    });
  };

  return (
    <ul
      className={classes}
      style={style}
      data-testid="test-menu"
      {...rest}
    >
      <MenuContext.Provider value={contextValue}>
        {renderChildren()}
      </MenuContext.Provider>
    </ul>
  );
};

Menu.defaultProps = {
  defaultIndex: '0',
  mode: 'horizontal',
  defaultOpenKeys: [],
}

export default Menu;
